import json
import requests
from loguru import logger
from pathlib import Path
from typing import Dict, Any, List, Optional
import asyncio
import aiohttp
import anyio
from contextlib import AsyncExitStack, suppress
from mcp import ClientSession
from mcp.client.sse import sse_client
import streamlit as st

from config import LOG_DIR, TONGYI_API_KEY, TONGYI_API_BASE, TONGYI_MODEL

# 配置日志
logger.add(
    LOG_DIR / "app.log",
    rotation="1 day",
    retention="7 days",
    level="INFO",
    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}"
)

# 日志初始化信息
logger.info(f"初始化AI购物助手，使用通义模型: {TONGYI_MODEL}")

# 存储全局MCP连接
_streams_context = None
_session_context = None
_session = None

# 安全关闭标志
_is_closing = False

async def connect_to_mcp_server(sse_url: str) -> ClientSession:
    """
    连接到MCP服务器
    :param sse_url: SSE服务器地址
    :return: 客户端会话
    """
    global _streams_context, _session_context, _session, _is_closing
    
    # 如果正在关闭，不允许重新连接
    if _is_closing:
        logger.warning("正在关闭连接，不允许重新连接")
        return None
    
    # 如果已经连接，直接返回会话
    if _session is not None:
        logger.info("已有活跃会话，复用现有连接")
        return _session
    
    try:
        logger.info(f"正在连接MCP服务器: {sse_url}")
        
        # 创建SSE客户端
        _streams_context = sse_client(url=sse_url)
        streams = await _streams_context.__aenter__()
        
        # 创建会话
        _session_context = ClientSession(*streams)
        _session = await _session_context.__aenter__()
        
        # 初始化
        await _session.initialize()
        logger.info("MCP客户端初始化完成")
        
        return _session
    except Exception as e:
        logger.error(f"连接MCP服务器失败: {str(e)}")
        
        # 清理资源
        await cleanup_mcp_connection()
        raise

async def cleanup_mcp_connection():
    """
    清理MCP连接
    """
    global _streams_context, _session_context, _session, _is_closing
    
    # 设置关闭标志
    _is_closing = True
    
    try:
        logger.info("开始清理MCP连接...")
        
        # 关闭会话
        if _session_context:
            logger.info("关闭会话...")
            with suppress(Exception):
                await _session_context.__aexit__(None, None, None)
            _session_context = None
            logger.info("会话已关闭")
        
        # 设置会话为None
        _session = None
        
        # 关闭流
        if _streams_context:
            logger.info("关闭流...")
            with suppress(Exception):
                await _streams_context.__aexit__(None, None, None)
            _streams_context = None
            logger.info("流已关闭")
        
        logger.info("MCP连接已清理")
    except Exception as e:
        logger.error(f"清理MCP连接时发生错误: {str(e)}")
        logger.exception("详细错误栈:")
    finally:
        # 重置关闭标志
        _is_closing = False
        
async def safe_disconnect():
    """
    安全断开连接
    """
    await cleanup_mcp_connection()
    logger.info("已安全断开连接")
    
async def check_connection_health():
    """
    检查连接健康状态
    """
    global _session
    
    try:
        if _session:
            # 尝试获取一个简单的响应
            logger.info("检查连接健康状态...")
            response = await _session.list_tools()
            logger.info(f"连接健康检查结果: {response is not None}")
            return response is not None
        else:
            logger.warning("没有活跃的会话连接")
            return False
    except Exception as e:
        logger.error(f"连接健康检查失败: {str(e)}")
        logger.exception("详细错误栈:")
        return False

async def get_tools_from_mcp(sse_url: str) -> List[Dict]:
    """
    从MCP服务器获取可用工具列表
    :param sse_url: SSE服务器地址
    :return: 工具列表
    """
    max_retries = 3
    retry_delay = 1  # 秒
    
    for attempt in range(max_retries):
        try:
            logger.info(f"尝试获取工具列表 (尝试 {attempt + 1}/{max_retries})")
            
            # 连接到MCP服务器
            session = await connect_to_mcp_server(sse_url)
            
            # 获取工具列表
            logger.info("正在获取工具列表...")
            response = await session.list_tools()
            tools = response.tools
            logger.info(f"成功获取工具列表: {[tool.name for tool in tools]}")
            
            # 将工具数据转换为标准格式
            tools_list = []
            for tool in tools:
                tools_list.append({
                    "name": tool.name,
                    "description": tool.description,
                    "parameters": tool.parameters if hasattr(tool, 'parameters') else tool.inputSchema
                })
            
            return tools_list
            
        except Exception as e:
            logger.error(f"获取工具列表时发生错误: {str(e)}")
            
            # 清理连接
            await cleanup_mcp_connection()
            
            if attempt < max_retries - 1:
                logger.info(f"等待 {retry_delay} 秒后重试...")
                await asyncio.sleep(retry_delay)
            else:
                logger.error("获取工具列表失败，已达到最大重试次数")
                return []
    
    return []

def call_tongyi_api(prompt: str, tools: list = None) -> Dict[str, Any]:
    """
    调用通义千问API (直接使用requests)
    :param prompt: 用户输入
    :param tools: 可用工具列表
    :return: API响应
    """
    try:
        # 请求头
        headers = {
            "Authorization": f"Bearer {TONGYI_API_KEY}",
            "Content-Type": "application/json"
        }
        
        # 系统提示，定义助手角色和行为
        system_prompt = """你是联想官方商城的智能导购助手。你的主要任务是：
1. 帮助用户了解和选购联想品牌的各类产品
2. 提供联想产品的详细信息、规格参数和价格
3. 根据用户需求推荐最适合的联想产品
4. 解答用户关于联想产品的各类问题

使用工具调用时，请遵循以下原则：
- 只推荐和介绍联想品牌的产品
- 准确理解用户需求，推荐合适的联想产品型号
- 详细解释产品特点和优势
- 提供产品参数、价格等具体信息
- 必要时对比不同型号的联想产品

你的回复应该：
- 专业且友好，像联想专卖店的导购一样服务用户
- 突出联想产品的优势和特色
- 使用准确的产品参数和描述
- 提供合理的购买建议
- 主动询问用户的具体需求和预算

示例回复：
"我为您找到几款适合的联想笔记本电脑：

1. ThinkPad X1 Carbon
   - 价格：¥9999
   - 特点：轻薄商务本的标杆，军规级别耐用性
   - 适合：商务人士、经常出差的用户

2. 拯救者Y9000P
   - 价格：¥8999
   - 特点：高性能游戏本，165Hz高刷新率屏幕
   - 适合：游戏玩家、设计师

您更倾向于哪种类型的笔记本？我可以为您详细介绍具体配置。"

请避免：
- 推荐或介绍非联想品牌的产品
- 使用不准确或过时的产品信息
- 过度承诺或夸大产品性能"""

        # 准备请求体 - 兼容模式
        request_data = {
            "model": TONGYI_MODEL,
            "temperature": 0.7,
            "messages": [
                {
                    "role": "system", 
                    "content": system_prompt
                },
                {
                    "role": "user", 
                    "content": prompt
                }
            ]
        }
        
        # 如果有工具，添加到请求中
        if tools and len(tools) > 0:
            # 转换工具格式为兼容模式需要的格式
            functions = []
            for tool in tools:
                functions.append({
                    "name": tool["name"],
                    "description": tool["description"],
                    "parameters": tool["parameters"]
                })
            
            # 添加函数到请求
            request_data["functions"] = functions
            # 设置为自动选择工具
            request_data["function_call"] = "auto"
        
        logger.info(f"正在调用通义API，提示词: {prompt}")
        if tools:
            logger.info(f"包含工具数量: {len(tools)}")
        
        # 发送请求
        response = requests.post(
            TONGYI_API_BASE,
            headers=headers,
            json=request_data,
            timeout=60
        )
        
        # 记录响应状态
        logger.info(f"通义API响应状态码: {response.status_code}")
        
        # 提前检查错误
        if response.status_code != 200:
            logger.error(f"通义API返回错误: {response.text}")
            return {"error": f"API调用失败: {response.status_code} - {response.text}"}
        
        # 解析响应
        result = response.json()
        logger.info(f"通义API响应成功")
        
        # 适配兼容模式的响应格式
        response_dict = {
            "id": result.get("id", ""),
            "model": result.get("model", ""),
            "created": result.get("created", 0),
            "output": {
                "choices": []
            }
        }
        
        # 解析选择项
        if "choices" in result and len(result["choices"]) > 0:
            choices = result["choices"]
            for i, choice in enumerate(choices):
                message = choice.get("message", {})
                choice_data = {
                    "index": i,
                    "message": {
                        "role": message.get("role", "assistant"),
                        "content": message.get("content", "")
                    },
                    "finish_reason": choice.get("finish_reason", "")
                }
                
                # 添加函数调用信息
                if "function_call" in message:
                    function_call = message["function_call"]
                    tool_calls = [{
                        "id": f"call_{i}",
                        "type": "function",
                        "function": {
                            "name": function_call.get("name", ""),
                            "arguments": function_call.get("arguments", "{}")
                        }
                    }]
                    choice_data["message"]["tool_calls"] = tool_calls
                
                response_dict["output"]["choices"].append(choice_data)
        
        # 如果没有选择项，添加一个默认的错误消息
        if len(response_dict["output"]["choices"]) == 0:
            response_dict["output"]["choices"].append({
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": "API返回了空结果。"
                },
                "finish_reason": "error"
            })
        
        logger.info(f"成功处理通义API响应")
        return response_dict
        
    except Exception as e:
        logger.error(f"调用通义API时发生错误: {str(e)}")
        return {"error": str(e)}

def call_tongyi_api_with_messages(messages: List[Dict]) -> Dict[str, Any]:
    """
    调用通义千问API，并提供完整的消息上下文
    :param messages: 完整对话历史
    :return: API响应
    """
    try:
        # 请求头
        headers = {
            "Authorization": f"Bearer {TONGYI_API_KEY}",
            "Content-Type": "application/json"
        }
        
        # 系统提示，定义助手角色和行为
        system_prompt = """你是一名专业的电商平台智能导购助手。请根据用户需求和工具返回的数据，提供专业的商品推荐和建议。

当你收到工具返回的数据时：
1. 分析数据并提取关键信息，如商品名称、价格、评分、特点等
2. 根据用户需求对数据进行筛选和排序
3. 以自然语言解释数据，不要直接输出原始JSON
4. 提供有见地的比较和推荐

重要：工具返回的结果可能包含"result"字段，这通常是JSON格式的字符串。你需要从中解析出商品信息。
如果在"result"字段中看到商品数据(如products数组)，必须详细介绍这些商品。

如果数据不足：
- 考虑是否需要更多工具调用来获取补充信息
- 告诉用户你已经找到了部分信息，并可以根据需要提供更多详细内容

你的回复应该：
- 友好自然，像真人导购一样与用户交流
- 重点突出最符合用户需求的商品
- 提供详细但不啰嗦的商品介绍
- 可能的情况下，提供多种选择和对比
- 主动提供后续建议，如"我可以帮您查看详细规格"或"您想了解更多类似商品吗？"

示例回复格式：
"我找到了几款适合您的商品：

1. [商品名称]
   价格：¥XXX
   特点：[简要描述主要特点]
   [为什么这款商品适合用户]

2. [商品名称]
   价格：¥XXX
   特点：[简要描述主要特点]
   [为什么这款商品适合用户]

您对哪一款更感兴趣？我可以为您提供更详细的信息。"

请避免：
- 不要直接复制工具返回的原始格式
- 不要使用技术术语如"根据工具调用结果"或"API返回"等
- 不要提及自己使用了工具，而是自然地融入回答中"""

        # 添加系统提示消息到消息列表的开头
        full_messages = [
            {
                "role": "system",
                "content": system_prompt
            }
        ]
        
        # 预处理消息，确保工具结果正确传递
        processed_messages = []
        for msg in messages:
            if msg.get("role") == "function":
                # 处理工具返回的结果，确保内容是字符串
                content = msg.get("content", "{}")
                # 如果内容是字典，转换为字符串
                if isinstance(content, dict):
                    processed_content = json.dumps(content, ensure_ascii=False)
                else:
                    processed_content = content
                
                # 处理可能的嵌套JSON
                try:
                    # 尝试解析内容，看是否为有效的JSON字符串
                    parsed_content = json.loads(processed_content)
                    # 检查是否包含result字段
                    if "result" in parsed_content:
                        result = parsed_content["result"]
                        # 如果result字段是字符串且看起来像JSON字符串，尝试解析
                        if isinstance(result, str) and (result.startswith("{") or result.startswith("[")):
                            try:
                                # 尝试解析JSON字符串
                                parsed_result = json.loads(result)
                                # 如果解析成功，替换为解析后的对象
                                parsed_content["result"] = parsed_result
                                # 重新序列化
                                processed_content = json.dumps(parsed_content, ensure_ascii=False)
                            except:
                                # 如果解析失败，保持原样
                                pass
                except:
                    # 如果解析失败，保持原样
                    pass
                
                # 创建新的消息对象
                processed_msg = {
                    "role": "function",
                    "name": msg.get("name", "unknown_function"),
                    "content": processed_content
                }
                processed_messages.append(processed_msg)
            else:
                # 其他类型的消息保持不变
                processed_messages.append(msg)
        
        # 添加处理后的用户对话历史
        full_messages.extend(processed_messages)
        
        # 准备请求体 - 直接使用提供的消息数组
        request_data = {
            "model": TONGYI_MODEL,
            "temperature": 0.7,
            "messages": full_messages
        }
        
        logger.info(f"使用工具结果再次调用通义API，消息数量: {len(full_messages)}")
        logger.info(f"发送给模型的消息内容: {json.dumps(full_messages, ensure_ascii=False)}")
        
        # 发送请求
        response = requests.post(
            TONGYI_API_BASE,
            headers=headers,
            json=request_data,
            timeout=60
        )
        
        # 记录响应状态
        logger.info(f"通义API响应状态码: {response.status_code}")
        
        # 提前检查错误
        if response.status_code != 200:
            logger.error(f"通义API返回错误: {response.text}")
            return {"error": f"API调用失败: {response.status_code} - {response.text}"}
        
        # 解析响应
        result = response.json()
        logger.info(f"通义API响应成功")
        
        # 适配兼容模式的响应格式
        response_dict = {
            "id": result.get("id", ""),
            "model": result.get("model", ""),
            "created": result.get("created", 0),
            "output": {
                "choices": []
            }
        }
        
        # 解析选择项
        if "choices" in result and len(result["choices"]) > 0:
            choices = result["choices"]
            for i, choice in enumerate(choices):
                message = choice.get("message", {})
                choice_data = {
                    "index": i,
                    "message": {
                        "role": message.get("role", "assistant"),
                        "content": message.get("content", "")
                    },
                    "finish_reason": choice.get("finish_reason", "")
                }
                
                # 添加函数调用信息
                if "function_call" in message:
                    function_call = message["function_call"]
                    tool_calls = [{
                        "id": f"call_{i}",
                        "type": "function",
                        "function": {
                            "name": function_call.get("name", ""),
                            "arguments": function_call.get("arguments", "{}")
                        }
                    }]
                    choice_data["message"]["tool_calls"] = tool_calls
                
                response_dict["output"]["choices"].append(choice_data)
        
        # 如果没有选择项，添加一个默认的错误消息
        if len(response_dict["output"]["choices"]) == 0:
            response_dict["output"]["choices"].append({
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": "API返回了空结果。"
                },
                "finish_reason": "error"
            })
        
        logger.info(f"成功处理通义API响应")
        return response_dict
        
    except Exception as e:
        logger.error(f"调用通义API时发生错误: {str(e)}")
        logger.exception("详细错误栈:")
        return {"error": str(e)}

def format_tool_call(tool_name: str, arguments: Dict) -> str:
    """
    格式化工具调用信息
    :param tool_name: 工具名称
    :param arguments: 工具参数
    :return: 格式化后的字符串
    """
    return f"调用工具 {tool_name}，参数：{json.dumps(arguments, ensure_ascii=False)}"

def format_tool_result(result: Dict) -> str:
    """
    格式化工具调用结果
    :param result: 工具调用结果
    :return: 格式化后的字符串
    """
    # 提取结果文本
    if "result" in result:
        result_text = result["result"]
        
        # 尝试解析JSON格式的结果
        try:
            # 如果result是JSON字符串，先解析它
            if isinstance(result_text, str) and (result_text.startswith("{") or result_text.startswith("[")):
                result_json = json.loads(result_text)
                
                # 检查是否为商品搜索结果
                if isinstance(result_json, dict) and "products" in result_json and "total" in result_json:
                    products = result_json["products"]
                    total = result_json["total"]
                    
                    if total == 0:
                        return "没有找到符合条件的商品"
                    
                    formatted_text = f"找到 {total} 件商品：\n\n"
                    for idx, product in enumerate(products, 1):
                        formatted_text += f"【{idx}】{product.get('name', '未命名商品')}\n"
                        formatted_text += f"💰 价格：¥{product.get('price', 0):.2f}\n"
                        if "category" in product:
                            formatted_text += f"📁 分类：{product.get('category', '')}\n"
                        if "rating" in product:
                            formatted_text += f"⭐ 评分：{product.get('rating', 0)} / 5\n"
                        if "stock" in product:
                            formatted_text += f"📦 库存：{product.get('stock', 0)} 件\n"
                        if "description" in product:
                            formatted_text += f"📝 描述：{product.get('description', '')}\n"
                        formatted_text += "\n"
                    
                    return f"工具调用结果：\n{formatted_text}"
            
            # 直接检查result_text本身是否为字典
            if isinstance(result_text, dict) and "products" in result_text and "total" in result_text:
                products = result_text["products"]
                total = result_text["total"]
                
                if total == 0:
                    return "没有找到符合条件的商品"
                
                formatted_text = f"找到 {total} 件商品：\n\n"
                for idx, product in enumerate(products, 1):
                    formatted_text += f"【{idx}】{product.get('name', '未命名商品')}\n"
                    formatted_text += f"💰 价格：¥{product.get('price', 0):.2f}\n"
                    if "category" in product:
                        formatted_text += f"📁 分类：{product.get('category', '')}\n"
                    if "rating" in product:
                        formatted_text += f"⭐ 评分：{product.get('rating', 0)} / 5\n"
                    if "stock" in product:
                        formatted_text += f"📦 库存：{product.get('stock', 0)} 件\n"
                    if "description" in product:
                        formatted_text += f"📝 描述：{product.get('description', '')}\n"
                    formatted_text += "\n"
                
                return f"工具调用结果：\n{formatted_text}"
        except:
            # 解析失败，使用默认格式
            pass
        
        # 检查是否包含错误信息
        if "error" in result:
            return f"工具调用结果 (出错)：\n{result_text}\n\n错误信息：{result['error']}"
        else:
            return f"工具调用结果：\n{result_text}"
            
    # 如果没有result字段，尝试直接解析整个结果
    try:
        # 检查是否为商品搜索结果
        if "products" in result and "total" in result:
            products = result["products"]
            total = result["total"]
            
            if total == 0:
                return "没有找到符合条件的商品"
            
            formatted_text = f"找到 {total} 件商品：\n\n"
            for idx, product in enumerate(products, 1):
                formatted_text += f"【{idx}】{product.get('name', '未命名商品')}\n"
                formatted_text += f"💰 价格：¥{product.get('price', 0):.2f}\n"
                if "category" in product:
                    formatted_text += f"📁 分类：{product.get('category', '')}\n"
                if "rating" in product:
                    formatted_text += f"⭐ 评分：{product.get('rating', 0)} / 5\n"
                if "stock" in product:
                    formatted_text += f"📦 库存：{product.get('stock', 0)} 件\n"
                if "description" in product:
                    formatted_text += f"📝 描述：{product.get('description', '')}\n"
                formatted_text += "\n"
            
            return f"工具调用结果：\n{formatted_text}"
    except:
        # 解析失败，使用默认格式
        pass
        
    # 如果没有result字段，则直接返回整个结果
    return f"工具调用结果：{json.dumps(result, ensure_ascii=False, indent=2)}"

async def execute_tool_call(tool_name: str, arguments: Dict) -> Dict:
    """
    执行工具调用
    :param tool_name: 工具名称
    :param arguments: 工具参数
    :return: 工具调用结果
    """
    global _session
    
    try:
        logger.info(f"执行工具调用: {tool_name}，参数: {arguments}")
        
        # 检查会话状态
        if not _session:
            logger.warning("会话不存在，尝试重新连接")
            try:
                # 尝试重新建立连接
                current_sse_url = st.session_state.get("sse_url", "http://127.0.0.1:8080/sse")
                _session = await connect_to_mcp_server(current_sse_url)
                if not _session:
                    error_msg = "无法重新连接到MCP服务器"
                    logger.error(error_msg)
                    mock_result = generate_mock_result(tool_name, arguments)
                    mock_result["error"] = error_msg
                    return mock_result
                logger.info("会话重连成功")
            except Exception as conn_error:
                error_msg = f"重新连接失败: {str(conn_error)}"
                logger.error(error_msg)
                mock_result = generate_mock_result(tool_name, arguments)
                mock_result["error"] = error_msg
                return mock_result
        
        # 执行工具调用
        try:
            logger.info(f"开始执行工具调用: {tool_name}")
            
            # 打印详细调试信息
            logger.info(f"会话类型: {type(_session)}")
            
            # 先尝试执行简单操作以测试连接是否活跃
            try:
                await _session.ping()
                logger.info("连接测试成功")
            except Exception as ping_error:
                logger.warning(f"连接测试失败: {str(ping_error)}，尝试重新连接")
                # 清理旧连接
                await cleanup_mcp_connection()
                # 重新连接
                current_sse_url = st.session_state.get("sse_url", "http://127.0.0.1:8080/sse")
                _session = await connect_to_mcp_server(current_sse_url)
                if not _session:
                    error_msg = "无法重新连接到MCP服务器"
                    logger.error(error_msg)
                    mock_result = generate_mock_result(tool_name, arguments)
                    mock_result["error"] = error_msg
                    return mock_result
                logger.info("会话重连成功")
            
            # 使用调用函数而不是使用name和arguments参数
            args_str = json.dumps(arguments)
            logger.info(f"执行调用: call_tool('{tool_name}', {args_str})")
            
            # 直接使用call_tool方法，避免复杂的尝试逻辑
            logger.info(f"使用call_tool接口")
            result = await _session.call_tool(tool_name, arguments)
                
            logger.info(f"调用成功，结果类型: {type(result)}")
            logger.info(f"工具调用结果: {result}")
            
            # 如果结果是字符串，直接返回
            if isinstance(result, str):
                return {"result": result}
            
            # 如果结果是复杂对象，尝试获取其文本表示
            if hasattr(result, 'content') and result.content:
                content_text = ""
                for item in result.content:
                    if hasattr(item, 'text'):
                        content_text += item.text
                    else:
                        content_text += str(item)
                return {"result": content_text}
            
            # 如果结果是复杂的字典，尝试以更友好的方式展示
            if isinstance(result, dict):
                return {"result": json.dumps(result, ensure_ascii=False, indent=2)}
            
            # 默认情况下转换为字符串
            return {"result": str(result)}
                
        except (BrokenPipeError, ConnectionError, ConnectionResetError, anyio.ClosedResourceError) as conn_error:
            error_details = f"连接已断开: {str(conn_error)}"
            logger.error(error_details)
            
            # 标记连接已断开
            await cleanup_mcp_connection()
            
            # 尝试重新连接一次
            try:
                logger.info("尝试重新连接并重试操作")
                current_sse_url = st.session_state.get("sse_url", "http://127.0.0.1:8080/sse")
                _session = await connect_to_mcp_server(current_sse_url)
                
                if _session:
                    # 重试操作
                    logger.info(f"重新连接成功，重试工具调用: {tool_name}")
                    result = await _session.call_tool(tool_name, arguments)
                    logger.info(f"重试调用成功，结果: {result}")
                    return {"result": str(result)}
                else:
                    logger.error("重新连接失败")
            except Exception as retry_error:
                logger.error(f"重试过程中发生错误: {str(retry_error)}")
            
            # 重试失败，返回模拟结果
            mock_result = generate_mock_result(tool_name, arguments)
            mock_result["error"] = error_details + " 服务器连接已断开并尝试重连失败，请手动重新连接。"
            return mock_result
            
        except Exception as tool_error:
            error_details = f"执行工具调用时的MCP错误: {str(tool_error)}"
            logger.error(error_details)
            logger.exception("详细错误栈:")
            # 返回模拟结果
            mock_result = generate_mock_result(tool_name, arguments)
            mock_result["error"] = error_details
            return mock_result
            
    except Exception as e:
        error_details = f"执行工具调用过程中发生错误: {str(e)}"
        logger.error(error_details)
        logger.exception("详细错误栈:")
        # 返回模拟结果
        mock_result = generate_mock_result(tool_name, arguments)
        mock_result["error"] = error_details
        return mock_result

def generate_mock_result(tool_name: str, arguments: Dict) -> Dict:
    """
    生成模拟的工具调用结果
    :param tool_name: 工具名称
    :param arguments: 工具参数
    :return: 模拟的结果
    """
    try:
        # 根据工具名称生成不同的模拟结果
        mock_result = {"result": "模拟结果"}
        
        if tool_name == "search_products":
            keywords = arguments.get("keywords", "未知商品")
            sort_by = arguments.get("sort_by", "default")
            mock_result = {
                "result": json.dumps({
                    "total": 3,
                    "products": [
                        {
                            "name": "联想ThinkPad X1 Carbon",
                            "price": 9999.00,
                            "category": "笔记本电脑",
                            "rating": 4.8,
                            "stock": 100,
                            "description": "第10代 英特尔酷睿i7 16GB 512GB SSD 14英寸"
                        },
                        {
                            "name": "联想拯救者Y9000P",
                            "price": 8999.00,
                            "category": "游戏本",
                            "rating": 4.7,
                            "stock": 50,
                            "description": "RTX4060 16GB 1TB SSD 16英寸 165Hz"
                        },
                        {
                            "name": "联想小新Pro16",
                            "price": 6999.00,
                            "category": "轻薄本",
                            "rating": 4.6,
                            "stock": 80,
                            "description": "AMD R7 16GB 512GB SSD 16英寸 2.5K"
                        }
                    ]
                }, ensure_ascii=False)
            }
            
        elif tool_name == "get_product_detail":
            product_id = arguments.get("product_id", "12345")
            mock_result = {
                "result": json.dumps({
                    "id": product_id,
                    "name": "联想ThinkPad X1 Carbon",
                    "price": 9999.00,
                    "category": "笔记本电脑",
                    "brand": "联想",
                    "model": "X1 Carbon 2024",
                    "rating": 4.8,
                    "stock": 100,
                    "sales": 500,
                    "description": "第10代 英特尔酷睿i7 16GB 512GB SSD 14英寸",
                    "specifications": {
                        "处理器": "Intel Core i7-1260P",
                        "内存": "16GB LPDDR5",
                        "存储": "512GB PCIe SSD",
                        "显示屏": "14英寸 2.2K IPS",
                        "显卡": "Intel Iris Xe Graphics",
                        "电池": "57Wh",
                        "重量": "1.12kg"
                    },
                    "features": [
                        "军规级别耐用性",
                        "快速充电技术",
                        "杜比音效",
                        "红外人脸识别",
                        "背光键盘"
                    ]
                }, ensure_ascii=False)
            }
            
        elif tool_name == "manage_shopping_cart":
            action = arguments.get("action", "查看")
            product_id = arguments.get("product_id", "")
            quantity = arguments.get("quantity", 1)
            
            if action == "add":
                mock_result = {"result": f"已将联想商品 (ID: {product_id}) 添加到购物车，数量: {quantity}。这是模拟结果。"}
            elif action == "remove":
                mock_result = {"result": f"已从购物车中移除联想商品 (ID: {product_id})。这是模拟结果。"}
            elif action == "update":
                mock_result = {"result": f"已更新购物车中联想商品 (ID: {product_id}) 的数量为 {quantity}。这是模拟结果。"}
            else:
                mock_result = {
                    "result": json.dumps({
                        "items": [
                            {
                                "id": "12345",
                                "name": "联想ThinkPad X1 Carbon",
                                "price": 9999.00,
                                "quantity": 1
                            },
                            {
                                "id": "12346",
                                "name": "联想拯救者Y9000P",
                                "price": 8999.00,
                                "quantity": 1
                            }
                        ],
                        "total": 18998.00
                    }, ensure_ascii=False)
                }
        
        elif tool_name == "manage_wishlist":
            action = arguments.get("action", "查看")
            product_id = arguments.get("product_id", "")
            
            if action == "add":
                mock_result = {"result": f"已将联想商品 (ID: {product_id}) 添加到收藏夹。这是模拟结果。"}
            elif action == "remove":
                mock_result = {"result": f"已从收藏夹中移除联想商品 (ID: {product_id})。这是模拟结果。"}
            else:
                mock_result = {
                    "result": json.dumps({
                        "items": [
                            {
                                "id": "12347",
                                "name": "联想小新Pro16",
                                "price": 6999.00
                            },
                            {
                                "id": "12348",
                                "name": "联想ThinkBook 16p",
                                "price": 7999.00
                            }
                        ]
                    }, ensure_ascii=False)
                }
        
        elif tool_name == "get_similar_products":
            product_id = arguments.get("product_id", "12345")
            mock_result = {
                "result": json.dumps({
                    "products": [
                        {
                            "id": "12349",
                            "name": "联想ThinkPad X1 Yoga",
                            "price": 10999.00,
                            "category": "笔记本电脑",
                            "rating": 4.7
                        },
                        {
                            "id": "12350",
                            "name": "联想ThinkPad T14",
                            "price": 8999.00,
                            "category": "笔记本电脑",
                            "rating": 4.6
                        },
                        {
                            "id": "12351",
                            "name": "联想ThinkPad P1",
                            "price": 12999.00,
                            "category": "工作站",
                            "rating": 4.8
                        }
                    ]
                }, ensure_ascii=False)
            }
        
        logger.info(f"生成了模拟结果: {mock_result}")
        return mock_result
    
    except Exception as e:
        logger.error(f"生成模拟结果时发生错误: {str(e)}")
        return {"result": f"模拟执行 {tool_name} 失败，参数: {json.dumps(arguments, ensure_ascii=False)}"} 